<template>
  <div style="padding: 10px;margin-bottom: 50px">
    <el-card style="margin: 10px 0;height: 80px;">
      <div style="display: flex">
        <div v-for="user in users" :key="user.username" style="width: 50%;margin-top: 10px">
          <span>{{ user.username }}</span>
          <i class="el-icon-chat-dot-round"
             style="margin-left: 10px;font-size: 16px;cursor: pointer;"
             @click="chatUser = user.username"></i>
          <span style="font-size: 12px;color: limegreen;" v-if="user.username === chatUser">connecting...</span>
        </div>
        <div style="width: 50%;margin-left: 780px">
          <!--        <el-button type="primary" size="big" @click="getLocalStream">获取本地</el-button>-->
          <el-button type="primary" size="big" @click="connection">连接远程</el-button>
          <el-button type="info" size="big" @click="closeConn">关闭</el-button>
          <el-button type="success" size="big" @click="createMedical" v-if="user.role !== 'ROLE_PATIENT'">创建病历</el-button>
        </div>
      </div>
    </el-card>
    <!--病历新增弹出框-->
    <el-dialog title="病历信息" :visible.sync="videoDialogFormVisible" width="60%" ref="img">
      <el-form :model="form" size="small">
<!--        <el-form-item label="患者用户名" label-width="100px">-->
<!--          <el-input v-model="form.patientName" autocomplete="off"></el-input>-->
<!--        </el-form-item>-->
        <el-form-item label="备注" label-width="100px">
          <el-input v-model="form.remark" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="病历内容" label-width="100px">
          <div id="richText"></div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
    <el-card>
      <!--视频出现区域-->
      <div style="border: 1px solid black;display: flex;text-align: center">
        <div style="border-right: 1px solid black;flex: auto">
          <div>本地</div>
          <div style="width: 352px;height: 320px">
            <video id="localVideo" autoplay="autoplay"></video>
          </div>
        </div>
        <div style="border-right: 1px solid black;flex: auto">
          <div>远程</div>
          <div style="width: 352px;height: 320px">
            <video id="remoteVideo" autoplay="autoplay"></video>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>

import Video from "@/views/front/Video";
// import E from "wangeditor";

let socket;
let peerConnection;
let toChatUser;
// var localStream = null;
let fromUser;

import E from "wangeditor"
import {serverIp, serverPort} from "../../../public/config";
let editor;
export default {
  name: "VideoChat",
  components: {Video},
  data() {
    return {
      users: [],
      user: {},
      chatUser: "",
      text: "",
      content: "",
      messages: [],
      dialogFormVisible: true,
      flag: false,
      localStream: {},
      form: {},
      videoDialogFormVisible: false
    }
  },
  methods: {
    init() {
      this.user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
      let username = this.user.username
      let _this = this
      if (typeof (WebSocket)  == "undefined") {
        console.log("您的浏览器不支持WebSocket")
        this.$message.error("您的浏览器不支持WebSocket")
      }else {
        console.log("您的浏览器支持WebSocket")
        let socketUrl = `ws://${serverIp}:${serverPort}/videoImserver/` + username;
        // let socketUrl = "ws://172.20.10.3:8085/videoImserver/" + username;
        if (socket != null) {
          socket.close()
          socket = null
        }
        //开启一个websocket服务
        socket = new WebSocket(socketUrl)
        //打开事件
        socket.onopen = function () {
          console.log("websocket已经打开")
        }
        //获得消息事件
        //浏览器接收消息，获得从服务器端发送过来的message
        socket.onmessage = function (msg) {

          console.log("客户端收到数据===" + msg.data)
          //对收到的json消息进行解析
          let data = JSON.parse(msg.data)

          if (data.users) {
            //获取在线人员信息
            //获取当前连接的所有用户信息，并且排除自身
            _this.users = data.users.filter(user => user.username !== username)
          }
          //第一步：视频请求消息(接收到视频通话的请求)
          if (data.event === "confirm") {
            // _this.$message.warning(data.data)
            _this.$confirm(data.data, '提示', {
              confirmButtonText: '同意',
              cancelButtonText: '拒绝',
              type: 'warning'
            }).then(() => {
              _this.$message({
                type: 'success',
                message: '已经反馈!'
              });
              //给用户发送同意信息
              socket.send(JSON.stringify({
                "event": "agree",
                "data": "对方同意视频，正在连接",
                "toUser": data.fromUser
              }));
              //将自己的flag设置为true，并且调用connection方法初始化peerConnection
              _this.flag = true
              _this.chatUser = data.fromUser
              toChatUser = data.fromUser

            }).catch(() => {
              _this.$message({
                type: 'info',
                message: '已拒绝'
              });
              //给用户发送拒绝信息
              socket.send(JSON.stringify({
                "event": "refuse",
                "data": "对方拒绝视频，请稍微再试",
                "toUser": data.fromUser
              }))
            });
          }
          //收到同意的消息
          if (data.event === "agree") {
            _this.$message.success(data.data)
            //将flag设置为true
            _this.flag = true
            peerConnection.createOffer(function (offer) {
                  peerConnection.setLocalDescription(offer)
                  socket.send(JSON.stringify({
                    "event": "_offer",
                    "data": offer,
                    "toUser": toChatUser,
                    "fromUser": _this.user.username
                  }))
                  console.log("offer已经给 " + toChatUser + " 发送")
                  console.log(offer)
                },
                function () {
                  console.log("offer创建失败")
                })
            //创建icecandidate
            peerConnection.onicecandidate = (event) => {
              if (event.candidate) {
                console.log("发起方发送icecandidate：" + event.candidate)
                socket.send(JSON.stringify({
                  "event": "_ice_candidate",
                  "data": {
                    "candidate": event.candidate
                  },
                  "fromUser": _this.user.username
                }))
              }
            }

          }
          //收到拒绝的消息
          if (data.event === "refuse") {
            _this.$message.error(data.data)
          }
          //收到offer
          if (data.event === "_offer") {
            console.log("收到 " + data.fromUser + "发送来的消息")
            peerConnection.setRemoteDescription(data.data)
            //发送answer
            peerConnection.createAnswer(function (answer) {
                  peerConnection.setLocalDescription(answer)
                  socket.send(JSON.stringify({
                    "event": "_answer",
                    "data": answer,
                    "toUser": toChatUser
                  }))
                  console.log("给 " + toChatUser + " 发送answer成功")
                },
                function () {
                  console.log("answer发送失败")
                })
            //发送icecandidate
            peerConnection.onicecandidate = (event) => {
              if (event.candidate) {
                console.log("接收方发送icecandidate：" + event.candidate)
                socket.send(JSON.stringify({
                  "event": "_ice_candidate",
                  "data": {
                    "candidate": event.candidate
                  },
                  "fromUser": _this.user.username
                }))
              }
            }
          }
          //收到answer
          if (data.event === "_answer") {
            console.log("已经收到answer，准备发送icecandidate")
            peerConnection.setRemoteDescription(data.data)
          }
          //收到icecandidate
          if (data.event === "_ice_candidate" && data.data.candidate) {
            console.log("客户端收到 " + data.fromUser + " 的icecandidate")
            if (data.fromUser !== _this.user.username) {
              console.log("客户端保存icecandidate")
              peerConnection.addIceCandidate(new RTCIceCandidate(data.data.candidate))
            }
          }
        };
        //关闭事件
        socket.onclose = function () {
          console.log("websocket已经关闭")
        };
        //发送错误事件
        socket.onerror = function () {
          console.log("websocket发生了错误")
        };
      }
    },
    //获取本地数据流
    async getLocalStream() {
      // 获取到媒体流后，调用函数初始化 RTCPeerConnection
      await this.init()
      await this.initPeerConnection()
      var constraints = {
        audio: true,
        // video: {
        //   width: { min: 1024, ideal: 1280, max: 1920 },
        //   height: { min: 776, ideal: 720, max: 1080 }
        // }
        video: { width: 530, height: 320 }
      }
      //判断是否有 navigator.mediaDevices，没有赋成空对象
      if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {}
      }
      //继续判断是否有 navigator.mediaDevices.getUserMedia，没有就采用 navigator.getUserMedia
      if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia = function (prams) {
          let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia
          //兼容获取
          if (!getUserMedia) {
            return Promise.reject(new Error("你的浏览器不支持getUserMedia"))
          }
          return new Promise(function (resolve, reject) {
            getUserMedia.call(navigator,prams,resolve,reject)
          })
        }
      }
      navigator.mediaDevices.getUserMedia(constraints).then(stream => {
        // 绑定本地媒体流到video标签用于输出
        let localVideo = document.getElementById('localVideo')
        this.localStream = stream
        peerConnection.addStream(stream)
        console.log("已经将本地视频流添加到peerConnection中")
        if ('srcObject' in localVideo) {
          localVideo.srcObject = this.localStream
          console.log(this.localStream)
        }else {
          localVideo.src = window.URL.createObjectURL(this.localStream)
          console.log(this.localStream)
        }
        localVideo.onloadedmetadata = function (e) {
          localVideo.play()
        }
      }).catch((err) => {
        console.log(err.name + ":" + err.message)
        this.$message.error(err.name + ":" + err.message)
      })
      // navigator.getMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia
      // navigator.getMedia({
      //   audio: true, // 是否开启麦克风
      //   video: true // 是否开启摄像头，这里还可以进行更多的配置
      // }, function(stream){
      //   // 获取到视频流stream
      //   // 绑定本地媒体流到video标签用于输出
      //   document.getElementById('localVideo').srcObject = stream
      //   localStream = stream
      //   // 都需要添加本地流
      //   stream.getTracks().forEach(function (track) {
      //     peerConnection.addTrack(track,stream)
      //     console.log(stream)
      //   })
      //   console.log("本地流添加完成")
      // }, function(error){
      //   this.$message.error("本地流获取失败")
      // })

    },
    //初始化PeerConnection
    async initPeerConnection() {
      // stun和turn服务器，打洞服务器设置
      var iceServer = {
        "iceServers": [
          {
            'urls': 'stun:47.93.247.196:3478'
          },
          {
            'urls': 'turn:47.93.247.196:3478',
            'credential': "pumpkin",
            'username': "admin"
          }
        ],
        mandatory: {offerToReceiveAudio:true,offerToReceiveVideo:true}
      }
      //初始化RTCPeerConnection
      window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
      peerConnection = new RTCPeerConnection(iceServer)
      console.log("peerConnection初始化完成")

      //先判断是否获取了本地流
      // if (localStream !== null || localStream !== "" || localStream !== undefined) {
      //
      // }else {
      //   this.$message.error("还未获取到本地视频流")
      // }
      // 监听是否有媒体流接入，如果有就赋值给 另一端 的 src
      // peerConnection.ontrack = function (event) {
      //   console.log("获取到远程媒体流")
      //   console.log(event.stream)
      //   document.getElementById('remoteVideo').srcObject = event.stream
      // }
      peerConnection.onaddstream = (event) => {
        document.getElementById('remoteVideo').srcObject = event.stream
      }
      //通过 oniceconnectionstatechange 方法来监测 ICE 连接的状态
      peerConnection.oniceconnectionstatechange = (evt) => {
        console.log("ice的连接状态发送改变：" + evt.target.iceConnectionState)
      }
    },
    connection() {
      toChatUser = this.chatUser
      if (toChatUser === "" || toChatUser === undefined || toChatUser === null) {
        this.$message.warning("请先选择视频对象")
        return
      }
      console.log(toChatUser)
      if (this.localStream !== null) {
        console.log("获取到了本地流：" + this.localStream)
      }else {
        this.$message.error("未获取到本地流")
        return;
      }
      // 判断对方是否同意
      if (!this.flag) {
        //先给视频对象发送想要视频的消息
        socket.send(JSON.stringify({
          "event": "confirm",
          "data": "用户名:" + this.user.nickname + " 想和你进行视频通话",
          "toUser": toChatUser,
          "fromUser": this.user.username
        }))
      }
      if (peerConnection === null || peerConnection === "" || peerConnection === undefined) {
        this.$message.error("未初始化peerConnection对象")
        return;
      }
    },
    closeConn() {
      peerConnection.close()
      document.getElementById("localVideo").srcObject = null
      this.$message.info("连接已经关闭")
    },
    //创建病历
    createMedical() {
      if (toChatUser === "" || toChatUser === undefined || toChatUser === null) {
        this.$message.warning("请先选择患者")
        return
      }
      this.dialogFormVisible = true
      this.form = {img: ''}
      this.$nextTick(() => {
        if (!editor) {
          editor = new E("#richText")
          editor.config.uploadImgServer = `http://${serverIp}:${serverPort}/file/uploadImg`
          editor.config.uploadFileName = 'file'
          editor.create()
        }
        //清除内容
        editor.txt.html('')
        if (this.$refs.img) {
          this.$refs.img.clearFiles()
        }
        if (this.$refs.file) {
          this.$refs.file.clearFiles()
        }
      })
    },
    //保存病历
    save() {
      const content = editor.txt.html()
      //手动赋值
      this.form.content = content
      this.request.post("/medicalRecord/videoSave/" + toChatUser,this.form).then(res => {
        console.log(this.form)
        console.log(res)
        if (res.code === '200') {
          this.dialogFormVisible = false
          this.form = {}
          this.$message.success("保存成功")
          this.load()
        }else {
          this.$message.error(res.msg)
        }
      })
    },
  },
  created() {
    // this.init()
    this.getLocalStream()
  }
}
</script>

<style>
.tip {
  color: white;
  text-align: center;
  border-radius: 10px;
  font-family: sans-serif;
  padding: 10px;
  width:auto;
  display:inline-block !important;
  display:inline;
}

.right {
  background-color: deepskyblue;
}
.left {
  background-color: forestgreen;
}
</style>